use crate::modules::interfaces::{RouteRuleInterface, GatewayConfigInterface};
use anyhow::Result;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock;
use tokio::time;
use ::time::OffsetDateTime;

/// 热加载管理器
#[derive(Clone)]
pub struct HotReloadManager {
    config_file_path: PathBuf,
    route_rules_file_path: PathBuf,
    watcher: Arc<RwLock<Option<RecommendedWatcher>>>,
    is_watching: Arc<RwLock<bool>>,
    last_config_hash: Arc<RwLock<String>>,
    last_rules_hash: Arc<RwLock<String>>,
}

/// 热加载配置
#[derive(Debug, Serialize, Deserialize)]
pub struct HotReloadConfig {
    pub enabled: bool,
    pub check_interval_ms: u64,
    pub config_file_path: String,
    pub route_rules_file_path: String,
    pub auto_reload: bool,
}

/// 热加载事件
#[derive(Debug, Clone)]
pub enum HotReloadEvent {
    ConfigFileChanged(PathBuf),
    RouteRulesFileChanged(PathBuf),
    ManualReloadRequested,
    ErrorOccurred(String),
}

impl HotReloadManager {
    /// 创建新的热加载管理器
    pub fn new(config_file_path: PathBuf, route_rules_file_path: PathBuf) -> Result<Self> {
        // 确保文件路径存在
        if let Some(parent) = route_rules_file_path.parent() {
            tokio::fs::create_dir_all(parent).await?;
        }
        if !route_rules_file_path.exists() {
            tokio::fs::File::create(&route_rules_file_path).await?;
        }

        Ok(Self {
            config_file_path,
            route_rules_file_path,
            watcher: Arc::new(RwLock::new(None)),
            is_watching: Arc::new(RwLock::new(false)),
            last_config_hash: Arc::new(RwLock::new(String::new())),
            last_rules_hash: Arc::new(RwLock::new(String::new())),
        })
    }

    /// 启动热加载监听
    pub async fn start_watching(&self) -> Result<()> {
        if !self.config_file_path.exists() || !self.route_rules_file_path.exists() {
            return Err(anyhow::anyhow!("文件路径不存在或不可访问"));
        }
    
        let mut is_watching = self.is_watching.write().await;
        if *is_watching {
            return Ok(());
        }

        // 创建文件监听器
        let (tx, mut rx) = tokio::sync::mpsc::channel(32);
        let mut watcher = notify::recommended_watcher(move |res| {
            if let Ok(event) = res {
                let _ = tx.blocking_send(event);
            }
        })?;

        // 监听配置文件
        watcher.watch(&self.config_file_path, RecursiveMode::NonRecursive)?;
        watcher.watch(&self.route_rules_file_path, RecursiveMode::NonRecursive)?;

        // 保存监听器
        {
            let mut watcher_guard = self.watcher.write().await;
            *watcher_guard = Some(watcher);
        }

        *is_watching = true;

        // 启动事件处理循环
        let manager = self.clone();
        tokio::spawn(async move {
            manager.handle_file_events(rx).await;
        });

        println!("热加载监听器已启动，监听文件: {:?}, {:?}", 
            self.config_file_path, self.route_rules_file_path);
        
        Ok(())
    }

    /// 停止热加载监听
    pub async fn stop_watching(&self) -> Result<()> {
        let mut is_watching = self.is_watching.write().await;
        if !*is_watching {
            return Ok(());
        }

        {
            let mut watcher_guard = self.watcher.write().await;
            *watcher_guard = None;
        }

        *is_watching = false;
        println!("热加载监听器已停止");
        
        Ok(())
    }

    /// 处理文件变化事件
    async fn handle_file_events(&self, mut rx: tokio::sync::mpsc::Receiver<notify::Event>) {
        while let Some(event) = rx.recv().await {
            match event.kind {
                notify::EventKind::Modify(_) => {
                    for path in event.paths {
                        if path == self.config_file_path {
                            println!("配置文件发生变化: {:?}", path);
                            if let Err(e) = self.handle_config_change().await {
                                println!("配置文件处理失败: {}", e);
                            }
                        } else if path == self.route_rules_file_path {
                            println!("路由规则文件发生变化: {:?}", path);
                            self.handle_route_rules_change().await;
                        }
                    }
                }
                notify::EventKind::Create(_) => {
                    for path in event.paths {
                        println!("新文件创建: {:?}", path);
                        if path == self.config_file_path || path == self.route_rules_file_path {
                            self.handle_config_change().await.ok();
                        }
                    }
                }
                notify::EventKind::Remove(_) => {
                    for path in event.paths {
                        println!("文件被删除: {:?}", path);
                        if path == self.config_file_path {
                            *self.last_config_hash.write().await = String::new();
                        } else if path == self.route_rules_file_path {
                            *self.last_rules_hash.write().await = String::new();
                        }
                    }
                }
                _ => {}
            }
        }
    }

    /// 处理配置文件变化
    async fn handle_config_change(&self) -> Result<()> {
        let content = match tokio::fs::read_to_string(&self.config_file_path).await {
            Ok(content) => content,
            Err(e) => return Err(anyhow::anyhow!("配置文件读取失败: {}", e)),
        };

        if !Self::validate_config(&content) {
            return Err(anyhow::anyhow!("配置文件内容无效"));
        }
    
        let current_hash = Self::calculate_hash(&content);
        let mut last_hash = self.last_config_hash.write().await;
        
        if current_hash != *last_hash {
            *last_hash = current_hash.clone();
            println!("配置文件内容已变化，准备重载...");
            // 触发配置重载逻辑
        }
    
        Ok(())
    }
    

    /// 处理路由规则文件变化
    async fn handle_route_rules_change(&self) {
        if let Ok(content) = tokio::fs::read_to_string(&self.route_rules_file_path).await {
            let current_hash = Self::calculate_hash(&content);
            let mut last_hash = self.last_rules_hash.write().await;
            
            if current_hash != *last_hash {
                *last_hash = current_hash.clone();
                println!("路由规则文件内容已变化，准备重载...");
                
                // 这里可以触发路由规则重载逻辑
                // 例如：通知网关服务重新加载路由规则
            }
        }
    }

    /// 计算字符串哈希
    fn calculate_hash(content: &str) -> String {
        use sha2::{Sha256, Digest};
        let mut hasher = Sha256::new();
        hasher.update(content.as_bytes());
        let result = hasher.finalize();
        hex::encode(result)
    }

    /// 手动触发重载
    pub async fn trigger_reload(&self) -> Result<()> {
        println!("手动触发热重载...");
        
        // 触发配置重载
        self.handle_config_change().await;
        
        // 触发路由规则重载
        self.handle_route_rules_change().await;
        
        Ok(())
    }

    /// 检查是否正在监听
    pub async fn is_watching(&self) -> bool {
        let is_watching = self.is_watching.read().await;
        *is_watching
    }

    /// 获取最后配置哈希
    pub async fn get_last_config_hash(&self) -> String {
        let hash = self.last_config_hash.read().await;
        hash.clone()
    }

    /// 获取最后路由规则哈希
    pub async fn get_last_rules_hash(&self) -> String {
        let hash = self.last_rules_hash.read().await;
        hash.clone()
    }
}

/// 热加载服务集成
pub struct HotReloadService {
    manager: HotReloadManager,
    gateway_service: Arc<tokio::sync::RwLock<Option<Arc<crate::modules::gateway_service::GatewayService>>>>,
}

impl HotReloadService {
    pub fn new(config_file_path: PathBuf, route_rules_file_path: PathBuf) -> Result<Self> {
        Ok(Self {
            manager: HotReloadManager::new(config_file_path, route_rules_file_path)?,
            gateway_service: Arc::new(tokio::sync::RwLock::new(None)),
        })
    }

    /// 设置网关服务引用
    pub async fn set_gateway_service(&self, gateway_service: Arc<crate::modules::gateway_service::GatewayService>) {
        let mut service_guard = self.gateway_service.write().await;
        *service_guard = Some(gateway_service);
    }

    /// 启动完整的热加载服务
    pub async fn start_service(&self) -> Result<()> {
        self.manager.start_watching().await?;
        
        // 启动定期检查
        let service = self.clone();
        tokio::spawn(async move {
            service.periodic_check().await;
        });

        Ok(())
    }

    /// 定期检查配置变化
    async fn periodic_check(&self) {
        let mut interval = time::interval(Duration::from_secs(30));
        
        loop {
            interval.tick().await;
            
            if self.manager.is_watching().await {
                // 定期验证文件完整性
                println!("定期热加载检查...");
            }
        }
    }

    /// 重新加载配置到网关服务
    pub async fn reload_config_to_gateway(&self, config_content: &str) -> Result<()> {
        if let Some(service) = &*self.gateway_service.read().await {
            // 解析配置并更新网关服务
            // 这里可以实现具体的配置解析逻辑
            println!("重新加载配置到网关服务");
        }
        
        Ok(())
    }

    /// 重新加载路由规则到网关服务
    pub async fn reload_rules_to_gateway(&self, rules_content: &str) -> Result<()> {
        if let Some(service) = &*self.gateway_service.read().await {
            // 解析路由规则并更新网关服务
            // 这里可以实现具体的规则解析逻辑
            println!("重新加载路由规则到网关服务");
        }
        
        Ok(())
    }
}

impl Clone for HotReloadService {
    fn clone(&self) -> Self {
        Self {
            manager: self.manager.clone(),
            gateway_service: self.gateway_service.clone(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::NamedTempFile;

    #[tokio::test]
    async fn test_hot_reload_manager_creation() {
        let temp_config = NamedTempFile::new().unwrap();
        let temp_rules = NamedTempFile::new().unwrap();
        
        let manager = HotReloadManager::new(
            temp_config.path().to_path_buf(),
            temp_rules.path().to_path_buf(),
        ).unwrap();
        
        assert!(!manager.is_watching().await);
    }

    #[tokio::test]
    async fn test_hash_calculation() {
        let content = "test content";
        let hash = HotReloadManager::calculate_hash(content);
        assert_eq!(hash.len(), 64); // SHA256哈希长度
    }
}